package main

import (
	"fmt"
	"math"
	"math/cmplx"
)

// 包内函数外，使用var关键字定义变量
var (
	aa     = 3
	ss     = "kkk"
	bb     = true //类型推断
	cc int = 1    //明确变量类型
)

func variableZeroValue() {
	var a int                   //var关键字定义变量，默认值0
	var s string                //var关键字定义变量，默认值null
	fmt.Printf("%d %q\n", a, s) //%d十进制  %q字符串
}

func variableInitialValue() {
	var a, b int = 3, 4  //定义相同类型的多个变量，并赋值
	var s string = "abc" //定义单个变量，明确变量类型
	fmt.Println(a, b, s)
}

func variableTypeDeduction() {
	var a, b, c, s = 3, 4, true, "def" //定义多个不同类型变量，并赋值，类型推断
	fmt.Println(a, b, c, s)
}

func variableShorter() {
	a, b, c, s := 3, 4, true, "def" //：定义变量，只能在函数内部使用等效var；=赋值，建议定义赋值变量这样写
	b = 5
	fmt.Println(a, b, c, s)
}

func euler() {
	fmt.Printf("%.3f\n",
		cmplx.Exp(1i*math.Pi)+1) //复数，验证欧拉公式
}

func triangle() {
	var a, b int = 3, 4
	fmt.Println(calcTriangle(a, b))
}

func calcTriangle(a, b int) int {
	c := int(math.Sqrt(float64(a*a + b*b)))
	return c
}

// 定义常量，关键字const
func consts() {
	const (
		filename = "abc.txt"
		a, b     = 3, 4 //未强制定义类型，根据需要自动转换相应类型
	)
	c := int(math.Sqrt(a*a + b*b))
	fmt.Println(filename, c)
}

// 枚举类型（特殊常量）定义，关键字const
func enums() {
	const (
		cpp        = iota //iota自增 0开始
		_                 //跳掉1
		python            //2
		golang            //3
		javascript        //4
	)

	const (
		b  = 1 << (10 * iota) //iota作为种子,表达式,2^0
		kb                    //2^10=1024
		mb
		gb
		tb
		pb
	)

	fmt.Println(cpp, javascript, python, golang)
	fmt.Println(b, kb, mb, gb, tb, pb)
}

func main() {
	fmt.Println("Hello world")
	variableZeroValue()
	variableInitialValue()
	variableTypeDeduction()
	variableShorter()
	fmt.Println(aa, ss, bb, cc)

	euler()
	triangle()
	consts()
	enums()
}

// goland快捷键
// Ctrl + 左键    查看方法
// Alt + <-/->   切换页面
